package com.sks.web.action.house;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;

import com.sks.bean.PageView;
import com.sks.bean.QueryResult;
import com.sks.bean.pojo.Area;
import com.sks.bean.pojo.AuditHistory;
import com.sks.bean.pojo.Building;
import com.sks.bean.pojo.Metro;
import com.sks.bean.pojo.MetroStation;
import com.sks.bean.pojo.PropertyType;
import com.sks.bean.privilege.Employee;
import com.sks.bean.privilege.SystemPrivilege;
import com.sks.core.SystemConstants;
import com.sks.service.house.AreaService;
import com.sks.service.house.AuditHistoryService;
import com.sks.service.house.BuildingService;
import com.sks.service.house.MetroService;
import com.sks.service.house.MetroStationService;
import com.sks.service.house.PropertyTypeService;
import com.sks.service.privilege.EmployeeService;
import com.sks.utils.SiteUrl;
import com.sks.utils.StringUtil;
import com.sks.utils.WebUtil;
import com.sks.web.action.BasicAction;
import com.sks.web.action.privilege.Permission;
import com.sks.web.formbean.house.BuildingForm;

@Controller("/cms/house/building")
public class BuildingAction extends BasicAction {
	@Resource(name = "buildingServiceBean") private BuildingService service;
	@Resource(name = "areaServiceBean") private AreaService areaService;
	@Resource(name = "propertyTypeServiceBean") private PropertyTypeService propertyTypeService;
	@Resource(name = "metroStationServiceBean") private MetroStationService metroStationService;
	@Resource(name = "metroServiceBean") private MetroService metroService;
	@Resource(name = "auditHistoryServiceBean") private AuditHistoryService ahService;
	@Resource(name = "employeeServiceBean") private EmployeeService employeeService;
	
	protected static String[] baseFields = {"developer", "developStatus", "status", "publishTime",
			"recommend", "address", "linkMan", "mobile", "intro", "areaId", "stationId", "lng", "lat"};
	
	protected static String[] proFields = {"propertyTypeId", "propertyCompany",
			"propertyPrice", "carNumber", "carRentPrice", "carSellPrice"};
	
	protected static String[] saleFields = {"sellAddress", "sellTel", "fax", "sellDate",
			"sellSchedule", "occupancyDate", "advantage"};
	
	protected static String[] conFields = {"space", "planSpace", "beginDate", "finishDate",
			"buildStructure", "yearLimit", "afforest", "cubage", "floorInfo", "deliverStandar"};
	
	protected static String[] surFields = {"trafficInfo", "mapInfo", "surround", "administration",
			"educate", "trade", "medical", "financial", "repast", "other"};
	
	protected static String[] hideFields = {"createTime", "lastUpdateTime"};
	
	protected static String[] onlyBase = mergeArrays(hideFields, proFields, saleFields, conFields, surFields);
	protected static String[] onlyPro = mergeArrays(hideFields, baseFields, saleFields, conFields, surFields);
	protected static String[] onlySale = mergeArrays(hideFields, baseFields, proFields, conFields, surFields);
	protected static String[] onlyCon = mergeArrays(hideFields, baseFields, proFields, saleFields, surFields);
	protected static String[] onlySur = mergeArrays(hideFields, baseFields, proFields, saleFields, conFields);

	@Permission(module = SystemPrivilege.MODULE_NAME_BUILDING, privilege = SystemPrivilege.PRIVILEGE_NAME_VIEW)
	public ActionForward list(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		BuildingForm formbean = (BuildingForm) form;
		PageView<Building> pageView = new PageView<Building>(12, formbean
				.getPage());
		StringBuffer jpql = new StringBuffer(" 1=1 ");
		List<Object> params = new ArrayList<Object>();
		if ("true".equals(formbean.getQuery())) { // 进行查询操作
			if (!StringUtil.isEmpty(formbean.getName())) {
				params.add("%" + formbean.getName() + "%");
				jpql.append(" and o.name like ?" + params.size());
			}
			
			if (!StringUtil.isEmpty(formbean.getStatus())) {
				params.add(formbean.getStatus());
				jpql.append(" and o.status = ?" + params.size());
			}
		}
		LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>();
		orderby.put("recommend", "desc");
		QueryResult<Building> qr = service.getScrollData(pageView.getFirstResult(),
				pageView.getMaxresult(), jpql.toString(), params.toArray(), orderby);
		pageView.setQueryResult(qr);
		request.setAttribute(PAGEVIEW, pageView);

		this.setReadOnly(request, "list");
		return mapping.findForward(LIST);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_BUILDING, privilege = SystemPrivilege.PRIVILEGE_NAME_VIEW)
	public ActionForward selectBuildingUI(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		list(mapping, form, request, response);
		return mapping.findForward(LIST + SystemConstants.OBJ_TYPE_BUILDING);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_BUILDING, privilege = SystemPrivilege.PRIVILEGE_NAME_UPDATE)
	public ActionForward addUI(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		this.saveToken(request);
		BuildingForm formbean = (BuildingForm) form;
		getBaseData(request, formbean);
		formbean.setMethod(ADD);
		return mapping.findForward(EDIT);
	}
	
	public void beforeadd(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ActionMessages errors = new ActionErrors();
		BuildingForm formbean = (BuildingForm) form;
		
		if (StringUtil.isEmpty(formbean.getName())) {
			errors.add("name", new ActionMessage("errors.required", getMessage("info.building.field.name")));
		}
		
		List params = new ArrayList();
		params.add(formbean.getName());
		StringBuffer jpql = new StringBuffer("o.name = ?" + params.size());
		if (EDIT.equals(formbean.getMethod())) {
			params.add(formbean.getBuildingId());
			jpql.append(" and o.buildingId <> ?" + params.size());
		}
		QueryResult<Building> m = service.getScrollData(-1, -1, jpql.toString(),
				params.toArray());
		if (null != m && m.getResultlist().size() > 0) {
			// 提示信息
			errors.add("name", new ActionMessage("errors.repeat", getMessage("info.building.field.name")));
			getBaseData(request, formbean);
		}
		saveErrors(request, errors);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_BUILDING, privilege = SystemPrivilege.PRIVILEGE_NAME_UPDATE)
	public ActionForward add(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		BuildingForm formbean = (BuildingForm) form;
		Building building = new Building();
		copyProperties(formbean, building);
		building.setBuildingId(null);
		building.setCreateTime(new Date());
		building.setLastUpdateTime(new Date());
		building.setStatus(Building.BUILDING_STATUS_NONE_PUBLISH);
		building.setArea(areaService.find(formbean.getAreaId(), false));
		building.setMetroStation(metroStationService.find(formbean.getMetroStationId(), false));
		service.save(building);
		formbean.setBuildingId(building.getBuildingId());
		formbean.setType("Base");
		return editUI(mapping, formbean, request, response);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_BUILDING, privilege = SystemPrivilege.PRIVILEGE_NAME_VIEW)
	public ActionForward editUI(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		this.saveToken(request);
		BuildingForm formbean = (BuildingForm) form;
		
		Boolean isBase = "Base".equals(formbean.getType());
		Building build = service.find(formbean.getBuildingId());
		copyProperties(build, formbean, formbean.getType());
		
		if (isBase) {
			MetroStation ms = build.getMetroStation();
			if (null != ms) {
				formbean.setMetroStationId(ms.getStationId());
				if (null != ms.getMetroByMetroId()) {
					formbean.setMetroId(ms.getMetroByMetroId().getMetroId());
				} else if (null != ms.getMetroByMetroId1()) {
					formbean.setMetroId(ms.getMetroByMetroId1().getMetroId());
				}
			}
			getBaseData(request, formbean);
			formbean.setCreateTime(build.getCreateTime());
		} else if ("Pro".equals(formbean.getType())) {
			getProData(request);
		}
		formbean.setMethod(EDIT);
		String returnForward = EDIT + (isBase ? "" : formbean.getType());
		//this.setReadOnly(request, "editUI");
		
		if (Building.BUILDING_STATUS_NONE_PUBLISH.equals(build.getStatus())) {//只有在未发布的状态下才能修改楼盘
			this.setReadOnly(request, "editUI");
		} else {
			request.setAttribute(SystemConstants.SYS_IS_READ_ONLY, true);
		}
		
		request.setAttribute(SystemConstants.SYS_CAN_AUDIT,
				WebUtil.hasPermission(request, SystemPrivilege.MODULE_NAME_BUILDING, SystemPrivilege.PRIVILEGE_NAME_AUDIT));
		
		return mapping.findForward(returnForward);
	}
	
	public void beforeedit(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		this.beforeadd(mapping, form, request, response);
	}
	
	@Permission(module = "building", privilege = "update")
	public ActionForward edit(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		BuildingForm formbean = (BuildingForm) form;
		Building build = service.find(formbean.getBuildingId());
		
		if (!Building.BUILDING_STATUS_NONE_PUBLISH.equals(build.getStatus())) {
			request.setAttribute(MESSAGE, getMessage("error.building.doNotEdit"));
			request.setAttribute("urladdress", "/cms/house/building.do?method=editUI&buildingId="
					+ formbean.getBuildingId() + "&type=" + formbean.getType());
			return mapping.findForward(MESSAGE);
		}
		
		copyProperties(formbean, build, formbean.getType());
		if ("Base".equals(formbean.getType())) {
			build.setArea(areaService.find(build.getAreaId(), false));
			build.setMetroStation(metroStationService.find(formbean.getMetroStationId(), false));
		} else if ("Pro".equals(formbean.getType())) {
			build.setPropertyType(propertyTypeService.find(build.getPropertyTypeId(), false));
		}
		
		service.update(build);
		formbean.setAreaId(null != build.getArea() ? build.getArea().getAreaId() : null);
		return editUI(mapping, formbean, request, response);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_BUILDING, privilege = SystemPrivilege.PRIVILEGE_NAME_UPDATE)
	public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		BuildingForm formbean = (BuildingForm) form;
		Building build = service.find(formbean.getBuildingId());
		String msg = null;
		if (null == build) {
			msg = getMessage("errors.nofound", getMessage("info.building.name"));
		} else if(!Building.BUILDING_STATUS_NONE_PUBLISH.equals(build.getStatus())) {
			msg = getMessage("error.building.doNotDelete");
		} else {
			service.delete(build.getBuildingId());
			msg = getMessage("info.delete.success", getMessage("info.building.name"));
		}
		
		request.setAttribute(MESSAGE, msg);
		request.setAttribute("urladdress", SiteUrl.readUrl("com.sks.web.action.house.building"));
		return mapping.findForward(MESSAGE);
	}
	
	private void getBaseData(HttpServletRequest request, BuildingForm formbean) {
		List<Area> tops = areaService.findAreas(true, null);
		List<Area> lows = new ArrayList<Area>(0);
		Integer areaId = formbean.getAreaId();
		if (null != areaId) {
			Area area = areaService.find(areaId);
			lows.addAll(area.getParentArea().getAreas());
			formbean.setTopAreaId(area.getParentArea().getAreaId());
		} else {
			//Area topArea = areaService.getDefaultTopArea();
			formbean.setTopAreaId(null);
			//lows.addAll(topArea.getAreas());
		}
		
		List<MetroStation> mss = new ArrayList<MetroStation>(0);
		List<Metro> ms = metroService.getScrollData().getResultlist();
		if (null != formbean.getMetroStationId()) {
			MetroStation stasion = metroStationService.find(formbean.getMetroStationId());
			if (null != stasion.getMetroByMetroId()) {
				mss.addAll(stasion.getMetroByMetroId().getMetroStationsForMetroId());
				formbean.setMetroId(stasion.getMetroByMetroId().getMetroId());
			} else if (null != stasion.getMetroByMetroId1()) {
				mss.addAll(stasion.getMetroByMetroId1().getMetroStationsForMetroId());
				formbean.setMetroId(stasion.getMetroByMetroId1().getMetroId());
			}
		} else {
			formbean.setMetroId(null);
		}
		
		request.setAttribute("mss", mss);
		request.setAttribute("ms", ms);
		request.setAttribute("tops", tops);
		request.setAttribute("lows", lows);
	}
	
	private void getProData(HttpServletRequest request) {
		List<PropertyType> pts = propertyTypeService.getScrollData().getResultlist();
		request.setAttribute("pts", pts);
	}
	
	private static String[] mergeArrays(String[] ... strings) {
		Integer newLen = 0;
		for (String[] strs : strings) {
			newLen += strs.length;
		}
		String[] newArray = new String[newLen];
		Integer temp = 0;
		for (int i = 0; i < strings.length; i++) {
			String[] strs = strings[i];
			System.arraycopy(strs, 0, newArray, temp, strs.length);
			temp += strs.length;
		}
		return newArray;
	}
	
	protected static void copyProperties(Object source, Object target, String type) {
		String[] ignorePros = null;
		if ("Base".equals(type)) {
			ignorePros = onlyBase;
		} else if ("Pro".equals(type)) {
			ignorePros = onlyPro;
		} else if ("Sale".equals(type)) {
			ignorePros = onlySale;
		} else if ("Con".equals(type)) {
			ignorePros = onlyCon;
		} else if ("Sur".equals(type)) {
			ignorePros = onlySur;
		}
		BeanUtils.copyProperties(source, target, ignorePros);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_BUILDING, privilege = SystemPrivilege.PRIVILEGE_NAME_AUDIT)
	public ActionForward changeStatus(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		BuildingForm formbean = (BuildingForm) form;
		formbean.setType("Base");
		Building building = service.find(formbean.getBuildingId());
		if (null != building) {
			String oldStatus = building.getStatus();
			String newStatus = formbean.getStatus();
			Date date = new Date();
			
			if (Building.BUILDING_STATUS_NONE_PUBLISH.equals(oldStatus)) {//未发布
				if (Building.BUILDING_STATUS_PUBLISHED.equals(newStatus)) {//已发布
					building.setStatus(Building.BUILDING_STATUS_PUBLISHED);
					building.setPublishTime(date);
				}
			} else if (Building.BUILDING_STATUS_PUBLISHED.equals(oldStatus)) {//已发布
				if (Building.BUILDING_STATUS_NONE_PUBLISH.equals(newStatus)) {//撤销发布
					building.setStatus(Building.BUILDING_STATUS_NONE_PUBLISH);
					building.setPublishTime(null);
				} else if (Building.BUILDING_STATUS_INVALIDATE.equals(newStatus)) {//发布->下架
					building.setStatus(Building.BUILDING_STATUS_INVALIDATE);
					building.setPublishTime(date);
				}
			} else if (Building.BUILDING_STATUS_INVALIDATE.equals(oldStatus)) {//已下架
				if (Building.BUILDING_STATUS_NONE_PUBLISH.equals(newStatus)) {//撤销下架返回未发布状态
					building.setStatus(Building.BUILDING_STATUS_NONE_PUBLISH);
					//building.setFinishTime(date);
				} else if (Building.BUILDING_STATUS_PUBLISHED.equals(newStatus)) {//撤销下架返回已发布状态
					building.setStatus(Building.BUILDING_STATUS_PUBLISHED);
					building.setPublishTime(date);
				}
			}
			service.update(building);
			
			Employee emp = WebUtil.getEmployee(request);
			emp = employeeService.find(emp.getUsername());
			AuditHistory ah = new AuditHistory(emp, AuditHistory.OBJ_TYPE_BUILDING, building.getBuildingId(), date, oldStatus, newStatus);
			ahService.save(ah);
		}
		return editUI(mapping, form, request, response);
	}
}
